/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "HalfSpace.h"
#include "Sphere.h"
#include "Box.h"

namespace liba
{
namespace math
{

HalfSpace::HalfSpace( const Plane<float> & plane )
:	plane( plane )
{}

Intersect::Type HalfSpace::intersects( const Sphere & sphere )const
{
	// Algorithm: sphere.center*plane.normal is the offset of the sphere's
	// center (i.e. the length of normal projection of the center onto
	// the normal), because the plane's normal is normalized
	// If offset > plane.offset + radius, then the sphere is contained in the
	// halfspace
	// If offset < plane.offset - radius, then the sphere is disjoint from the
	// halfspace
	// center_offset_min_plane_offset subtracts the plane.offset, to save one
	// subtraction in the two if statements.
	Intersect::Type ret( Intersect::INTERSECTS );
	float center_offset_min_plane_offset( Vector3<float>::dot( sphere.get_center(), plane.get_normal() ) -
									 plane.get_offset() );
	if( center_offset_min_plane_offset > sphere.get_radius() )
		ret = Intersect::CONTAINS;
	else
		if( center_offset_min_plane_offset < -sphere.get_radius() )
			ret = Intersect::DISJOINT;

	return ret;    
}

Intersect::Type HalfSpace::intersects( const Box & box )const
{
	if( plane.intersects( box ) )
		return Intersect::INTERSECTS;

	float d = plane.distance( box.get_center() );
	if( d > 0 )
		return Intersect::CONTAINS;
	
	return Intersect::DISJOINT;
}

bool HalfSpace::containts( const Vector3<float> & point )const
{
    return Vector3<float>::dot( point, plane.get_normal() ) > plane.get_offset();
}

} // namespace math
} // namespace liba



